package com.lee.security.provider.validate.sms;

import com.lee.properties.CommonProperties;
import com.lee.repository.EmployeeRepository;
import com.lee.security.properties.SecurityConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * @author lee
 * @date 2018年12月7日
 */
@Component
public class SmsSendPermission {

    @Autowired
    private CommonProperties commonProperties;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private EmployeeRepository employeeRepository;

    private static final long sendInterval = 58L;

    private static final int sendMaxSum = 240;

    private static final int resetTimeHour = 9;

    public void sceneCheck(String mobile, String scene) {
        if (!commonProperties.getSmsScene().containsKey(scene))
            throw new AuthenticationServiceException("不支持的短信验证场景:" + scene);

        boolean registered = commonProperties.getRegisteredScene().get(scene);
        boolean mobileExist = employeeRepository.existsByUsername(mobile);
        if (registered ^ mobileExist)
            throw new AuthenticationServiceException(StringUtils.join("手机号", mobile, mobileExist ? "已注册" : "未注册"));

        if (StringUtils.equals(scene, SecurityConstants.CURRENT_AUTH_SCENE) &&
                !StringUtils.equals(mobile, SecurityContextHolder.getContext().getAuthentication().getName()))
            throw new AuthenticationServiceException("登录信息异常或未登录");
    }

    /**
     * 验证今日是否达到最大信息发送次数
     *
     * @return
     */

    /*public void sendMax(String mobile, String keyPrefix) {

        String countKey = buildKey(mobile, keyPrefix);
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String sendSumStr = valueOperations.get(countKey);
        if (StringUtils.isNotBlank(sendSumStr) && Pattern.matches("[0-9]*", sendSumStr)) {
            Integer sendSum = Integer.valueOf(sendSumStr);
            if (sendSum < sendMaxSum) {
                redisTemplate.boundValueOps(countKey).increment(1);
                return;
            } else {
                throw new AuthenticationServiceException(StringUtils.join("手机号", mobile, "已达到最大发送次数"));
            }
        } else {
            Long timeDuration = TimeDurationUtil.timeDuration(resetTimeHour, 0, 0);
            valueOperations.set(countKey, "1", timeDuration, TimeUnit.SECONDS);
            return;
        }
    }*/

    /***
     * 验证是否在信息发送间隔时间内**
     *
     * @return
     */
    public void sendInterval(String mobile, String keyPrefix) {
        String intervalKey = buildKey(mobile, keyPrefix);
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        if (StringUtils.isEmpty(valueOperations.get(intervalKey)))
            valueOperations.set(intervalKey, mobile, Duration.ofSeconds(sendInterval));
        else throw new AuthenticationServiceException(StringUtils.join("手机号", mobile, "请求过于频繁"));
    }

    private final String buildKey(String mobile, String keyPrefix) {
        return StringUtils.isNotBlank(mobile) ? keyPrefix + mobile : "";
    }

}
